<?php

namespace app\common\business;

use app\common\lib\Arr;
use app\common\model\mysql\SystemCategory;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\Exception;
use think\Model;

class Category
{
    public $model = null;

    public function __construct()
    {
        $this->model = new SystemCategory();
    }

    /**
     * 查询配置树
     * @return array
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getAllTree(): array
    {
        $data=$this->model->getAllTree();
        return Arr::getTree($data);
    }

    /**
     * 新增/保存数据
     * @param $data
     * @return bool
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException|Exception
     */
    public function save($data): bool
    {
        if(empty($data['id'])){
            unset($data['id']);
        }
        return $this->model->saveData($data);
    }

    /**
     * 根据id修改状态
     * @param $data
     * @return bool
     * @throws DataNotFoundException
     * @throws DbException
     * @throws Exception
     * @throws ModelNotFoundException
     */
    public function updateStatus($data): bool
    {
        if(empty($data['id'])){
            throw new Exception('参数错误');
        }
        return $this->model->updateStatus($data);
    }

    /**
     * 根据id删除
     * @param $id
     * @return bool
     * @throws Exception
     */
    public function deleteById($id): bool
    {
        if(empty($id)){
            throw new Exception('参数错误');
        }
        $isChild=self::checkIsChild($id);
        if($isChild){
            throw new Exception('请先删除子级配置');
        }
        return $this->model->deleteById($id);
    }

    /**
     * 查询是否存在子级
     * @param $id
     * @return bool
     */
    public function checkIsChild($id): bool
    {
        return ($this->model->where(['pid'=>$id])->count())>0;
    }

    /**
     * 根据分类名称获取配置
     * @param string $name
     * @return array
     * @throws Exception
     */
    public function getCategoryByName(string $name=''): array
    {
        if(empty($name)){
            throw new Exception('配置类名称不能为空');
        }
        $pid=$this->model->getPidByName($name);
        if(empty($pid)){
            throw new Exception('数据不存在');
        }
        $data=$this->model->getCategoryByPid($pid['id']);
        return $data->isEmpty()?[]:$data->toArray();
    }

    /**
     * 根据分类名称获取配置
     * @param array $name
     * @return array
     * @throws DataNotFoundException
     * @throws DbException
     * @throws Exception
     * @throws ModelNotFoundException
     */
    public function getCategoryMultipleByName(array $name): array
    {
        if(empty($name)){
            throw new Exception('配置类名称不能为空');
        }

        $pid=$this->model->getCategoryByName(array_keys($name));
        if($pid->isEmpty()){
            throw new Exception('未查询到分类数据');
        }
        $pid=$pid->toArray();

        $category=$this->model->getCategoryMultipleByPid(array_map('array_shift',$pid));
        if($category->isEmpty()){
            throw new Exception('未查询到子级数据');
        }
        $category=$category->toArray();
        $newCategory=[];
        foreach ($category as $v){
            $newCategory[$v['pid']][]=$v;
        }
        $data=[];
        foreach ($pid as $v){
            $data[$name[$v['name']]]= $newCategory[$v['id']] ?? [];
        }
        return $data;
    }

    /**
     * 查询字典
     * @return array
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function categoryDictionaries(): array
    {
        $data=$this->model->getDictionaries();
        $data=$data->isEmpty()?[]:$data->toArray();
        $newData=[];
        foreach ($data as $v){
            $newData[$v['id']]=$v['name'];
        }
        return $newData;
    }

    /**
     * 根据名称获取配置
     * @param $name
     * @return SystemCategory|array|mixed|Model|null
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getCategoryIdByName($name){
        return $this->model->getCategoryIdByName($name);
    }

    /**
     * @param $where
     * @param $page
     * @param $limit
     * @param $field
     * @return array
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getListByWhere($where,$page,$limit,$field='*'){
        $where[] = ['status','=',config("status.mysql.table_normal")];
        if ($page!=0 && $limit !=0){
            $list = $this->model->getPageListByWhere($where,$page,$limit,$field);
        }else{
            $list = $this->model->getNormalListByWhere($where,$field);
        }
        if($list->isEmpty()){
            return [];
        }
        return $list->toArray();
    }

    public function getListByWhereWithOrder($where,$page,$limit,$order='id desc',$field='*'){
        $where[] = ['status','=',config("status.mysql.table_normal")];
        if ($page!=0 && $limit !=0){
            $list = $this->model->getPageListByWhereWithOrder($where,$page,$limit,$order,$field);
        }else{
            $list = $this->model->getNormalListByWhereWithOrder($where,$order,$field);
        }
        if($list->isEmpty()){
            return [];
        }
        return $list->toArray();
    }

    public function getNormalById($id)
    {
        $data = $this->model->getById($id);
        if (!$data || $data->status != config("status.mysql.table_normal")) {
            return [];
        }
        return $data->toArray();
    }

    /**
     * 验证提交值是否有效值
     * @param $name
     * @param $value
     * @return bool
     * @throws Exception
     */
    public function checkValidValueByName($name,$value){
        $dictionary = $this->getCategoryByName($name);
        if (empty($dictionary)){
            throw new Exception('未查询到分类数据');
        }

        $idArr = array_column($dictionary,'id');
        if (!in_array($value,$idArr)){
            throw new Exception($name.'数据异常');
        }
        return true;
    }

    /**
     * 通过pid返回树状结构数据
     * @param $pid
     * @return array
     */
    public function getCategoryByPid($pid){
        $map = [['pid','=',$pid]];
        $data = $this->getListByWhereWithOrder($map,0,0,'sort desc,id asc','id,pid,name');
        if (empty($data)){
            return [];
        }

        $data1 = [];
        $data2 = [];

        //第二层
        $subIdArr1 = array_column($data, 'id');
        $map1 = [['pid', 'in', $subIdArr1]];
        $data1 = $this->getListByWhere($map1, 0, 0, 'id,pid,name');
        if (!empty($data1)){
            //第三层
            $subIdArr2 = array_column($data1, 'id');
            $map2 = [['pid', 'in', $subIdArr2]];
            $data2 = $this->getListByWhere($map2, 0, 0, 'id,pid,name');
        }

        $data = array_merge_recursive($data, $data1,$data2);
        return $data;
    }
}
